/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package im.general;

import im.messages.BaseMessage;
import im.numgenerator.PseudoRandomGenerator;
import im.resources.UpdateResources;
import im.resources.UpdateResourcesBehaviour;
import im.resources.model.ResourcesModel;
import jade.core.AID;
import jade.core.Agent;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.UnreadableException;
import jade.wrapper.ControllerException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author bluejack
 */
public abstract class BaseAgent extends Agent {
    protected String container;
    protected ResourcesModel resources_model;
        //this is used for generating random values
    protected long seedRand;
    //protected Logger generalLogger = null;
    protected int messageCounter = 0;
    protected PseudoRandomGenerator pr_gen;
    protected AgentLogBehaviour logBehaviour=null;
    //protected Vector<String> CHs;


    protected Hashtable<String,Double> CH_idx;

    public Hashtable<String,Double> getCHs() {
        return CH_idx;
    }

    public abstract boolean updateResources();

    
    public void setCHs(Hashtable<String,Double> Chs) {
        if( Chs == null )
            System.out.println("ERRORE IN SET CH");
        this.CH_idx = new Hashtable<String,Double>(Chs);
    }
    

    public String getContainerName() {
        try {
            //return this.getContainerController().getName();
            return this.getContainerController().getContainerName();
        } catch (ControllerException ex) {
            Logger.getLogger(BaseAgent.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    @Override
    public void setup() {
        Object [] argv = this.getArguments();
        //generalLogger = (Logger) argv[0];


        CH_idx = new Hashtable<String,Double>();

        try {
            //NOTE: daniele changed this for Agent.doClone compatibility
            //container = (String)argv[0];
            container = this.getContainerController().getContainerName();
        } catch (ControllerException ex) {
            Logger.getLogger(BaseAgent.class.getName()).log(Level.SEVERE, null, ex);
        }


        logBehaviour = new AgentLogBehaviour(this);
        addBehaviour(logBehaviour);
    }

    public void sendMessage(ACLMessage msg) {
        //System.out.println("SENDING MESSAGE "+msg.toString());
        int receivers = 0;
        Iterator i = msg.getAllReceiver();
        while(i.hasNext()) {
            receivers++;
            i.next();
            /*AID r = (AID) i.next();
            try {
                //receivers++;
                if (this.getContainerController().getAgent(r.getLocalName()) != null) {
                    
                }
            } catch (ControllerException ex) {
                receivers++;//Logger.getLogger(BaseAgent.class.getName()).log(Level.SEVERE, null, ex);
            }*/
        }

        messageCounter += receivers;

        //String sender = this.getLocalName();

        super.send(msg);
    }

    public int readMessageCount() {
        int count = messageCounter;
        messageCounter = 0;
        return count;
    }

    public void addReceiver(String recipient, ACLMessage msg) {
        if(recipient==null)
            return;
        AID ar = null;
        if(recipient.contains("@"))
            ar = new AID(recipient, AID.ISGUID);
        else
            ar = new AID(recipient, AID.ISLOCALNAME);
        //ar.setName(recipient);
        msg.addReceiver(ar);
    }


    public void addReceivers(Iterator iterator, ACLMessage msg) {
        //for(String recipient = (String) iterator.next(); iterator.hasNext(); recipient = (String) iterator.next()) {
        while(iterator.hasNext()) {
            addReceiver((String) iterator.next(), msg);
        }
    }

    /*public ACLMessage getCopy(ACLMessage msg) {
        ACLMessage nmsg = new ACLMessage(msg.getPerformative());

        nmsg.setEncoding(msg.getEncoding());

        return nmsg;
    }*/

    protected void copyContent( ACLMessage smsg, ACLMessage dmsg) {
        try {
            try {
                dmsg.setContentObject(smsg.getContentObject());
            } catch (UnreadableException ex) {
                Logger.getLogger(BaseAgent.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (IOException ex) {
            Logger.getLogger(BaseAgent.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void forwardToES(ACLMessage msg) {
        ACLMessage nmsg = new BaseMessage(msg.getPerformative());
        nmsg.setSender(this.getAID());
        //nmsg.setMessagePayload(msg.getMessagePayload());

        AID es = new AID();
        es.setName(Config.EVENT_SERVICE_NAME);
        nmsg.addReceiver(es);

        this.sendMessage(nmsg);
    }

    public void forwardToContacts(ACLMessage msg, Hashtable ht) {
        BaseMessage nmsg = new BaseMessage(msg.getPerformative());
        nmsg.setSender(this.getAID());

        for(Enumeration hn = ht.keys(); hn.hasMoreElements(); ) {
            AID head = new AID();
            head.setName((String) hn.nextElement());
            nmsg.addReceiver(head);
        }

        this.sendMessage(nmsg);
    }

    public abstract int getAttachedNodes();

    public abstract void setAttachedNodes(int attachedNodes);
    public void updAttachedNodes() {};
}
